#ifndef CAFFEINE_PHYSICS_IPHYSICSBODY_HPP
#define CAFFEINE_PHYSICS_IPHYSICSBODY_HPP

#include "Common.hpp"
#include "Math/Vector.hpp"
#include "Physics/PhysWorld.hpp"

#include "Box2D/Dynamics/b2Body.h"
#include "Box2D/Dynamics/b2Fixture.h"
#include "Box2D/Dynamics/b2World.h"

namespace Entity
{
	class IEntity;
}

namespace Physics
{
	enum PhysicsBody
	{
		PHYS_BODYTYPE_STATIC = 0,
		PHYS_BODYTYPE_KINEMATIC,
		PHYS_BODYTYPE_DYNAMIC
	};

	enum PhysicsShape
	{
		PHYS_SHAPE_BOX = 0
	};

	class IBody
	{
	public:
		IBody( Entity::IEntity *setEnt );
		virtual ~IBody( void );

		virtual void Initialise( const int bodyType, const int shapeType, const Math::Vectorf &size );

		virtual Entity::IEntity *GetEntity( void );

		virtual bool IsAsleep( void ) const;
		virtual void SetAsleep( const bool asleep );

		virtual void ApplyForce( const Math::Vectorf &force, const Math::Vectorf &point );
		virtual void ApplyAngularForce( const float torque );
		virtual void ApplyLinearForce( const Math::Vectorf &force );

		virtual float GetAngle( void ) const;
		virtual void SetAngle( const float angle );

		virtual bool GetRotationFixed( void ) const;
		virtual void SetRotationFixed( const bool fixed );

		virtual Math::Vectorf GetPosition( void ) const;
		virtual void SetPosition( const Math::Vectorf &pos );

		virtual float GetDensity( void ) const;
		virtual void SetDensity( const float density );

		virtual float GetFriction( void ) const;
		virtual void SetFriction( const float friction );

		virtual float GetMass( void ) const;
		virtual void SetMass( const float mass );

		virtual float GetRestitution( void ) const;
		virtual void SetRestitution( const float restitution );

		virtual Math::Vectorf GetLocalCentreOfMass( void ) const;
		virtual Math::Vectorf GetWorldCentreOfMass( void ) const;

		virtual float GetAngularVelocity( void ) const;
		virtual void SetAngularVelocity( const float angVel );

		virtual float GetAngularDamping( void ) const;
		virtual void SetAngularDamping( const float damping );

		virtual Math::Vectorf GetLinearVelocity( void ) const;
		virtual void SetLinearVelocity( const Math::Vectorf &vel );

		virtual float GetLinearDamping( void ) const;
		virtual void SetLinearDamping( const float damping );
	private:
		b2Fixture *GetFixture( void ) const;

		Entity::IEntity *ent;
		PhysWorld *world;

		b2Body *body;
	};
}

#endif //CAFFEINE_IPHYSICSBODY_HPP